package org.system.core.service.system;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.system.core.annotation.DataScope;
import org.system.core.domain.entity.*;
import org.system.core.exception.AuthorityException;
import org.system.core.exception.ServiceException;
import org.system.core.mapper.system.SysRoleDeptMapper;
import org.system.core.mapper.system.SysRoleMapper;
import org.system.core.mapper.system.SysRoleMenuMapper;
import org.system.core.mapper.system.SysUserRoleMapper;
import org.system.core.utils.MessageUtils;
import org.system.core.utils.SecurityUtils;
import org.system.core.utils.StringUtils;
import org.system.core.utils.spring.SpringUtils;

import java.util.*;

/**
 * @author baoRoot
 */
@Service
public class SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    private SysRoleDeptMapper sysRoleDeptMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    public Set<String> selectRolePermissionByUserId(Long userId) {
        List<SysRole> perms = sysRoleMapper.selectRolePermissionByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (SysRole perm : perms) {
            if (StringUtils.isNotNull(perm)) {
                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
            }
        }
        return permsSet;
    }

    @DataScope(deptAlias = "d")
    public List<SysRole> selectRoleList(SysRole role) {
        return sysRoleMapper.selectRoleList(role);
    }

    public List<SysRole> selectRoleAll() {
        return SpringUtils.getAopProxy(this).selectRoleList(new SysRole());
    }

    public List<SysRole> selectRolesByUserId(Long userId) {
        // todo 这里只获取当前角色
//        return sysRoleMapper.selectRolePermissionByUserId(userId);
        List<SysRole> userRoles = sysRoleMapper.selectRolePermissionByUserId(userId);
        List<SysRole> roles = selectRoleAll();
        for (SysRole role : roles) {
            for (SysRole userRole : userRoles) {
                if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) {
                    role.setFlag(true);
                    break;
                }
            }
        }
        return roles;
    }

    public void checkRoleDataScope(Long roleId) {
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            SysRole role = new SysRole();
            role.setRoleId(roleId);
            List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
            if (StringUtils.isEmpty(roles)) {
                throw new AuthorityException("没有权限访问角色数据！");
            }
        }
    }

    public boolean checkRoleNameUnique(SysRole role) {
        Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
        SysRole info = sysRoleMapper.checkRoleNameUnique(role.getRoleName());
        return !StringUtils.isNotNull(info) || info.getRoleId().longValue() == roleId.longValue();
    }

    public boolean checkRoleKeyUnique(SysRole role) {
        Long roleId = StringUtils.isNull(role.getRoleId()) ? -1L : role.getRoleId();
        SysRole info = sysRoleMapper.checkRoleKeyUnique(role.getRoleKey());
        return !StringUtils.isNotNull(info) || info.getRoleId().longValue() == roleId.longValue();
    }

    public SysRole selectRoleById(Long roleId) {
        checkRoleDataScope(roleId);
        return sysRoleMapper.selectRoleById(roleId);
    }

    public void checkUserUnique(SysRole role) {
        if(!checkRoleNameUnique(role)) {
            throw new ServiceException(MessageUtils.message("system.role.exist_name"));
        }
        if(!checkRoleKeyUnique(role)){
            throw new ServiceException(MessageUtils.message("system.role.exist_role"));
        }
    }

    @Transactional
    public void createRole(SysRole role) {
        checkUserUnique(role);
        role.setCreateBy(SecurityUtils.getUsername());
        sysRoleMapper.insertRole(role);
        if(insertRoleMenu(role) <= 0) {
            throw new ServiceException(MessageUtils.message("system.monitor.add_error"));
        }
    }

    @Transactional
    public void authDataScope(SysRole role) {
        checkRoleAllowed(role);
        checkRoleDataScope(role.getRoleId());
        sysRoleMapper.updateRole(role);
        sysRoleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId());
        if (insertRoleDept(role) <= 0) {
            throw new ServiceException(MessageUtils.message("system.monitor.edit_error"));
        }
    }

    public int countUserRoleByRoleId(Long roleId) {
        return sysUserRoleMapper.countUserRoleByRoleId(roleId);
    }

    public void deleteRoleByIds(Long[] roleIds) {
        for (Long roleId : roleIds) {
            checkRoleAllowed(new SysRole(roleId));
            checkRoleDataScope(roleId);
            SysRole role = selectRoleById(roleId);
            if (countUserRoleByRoleId(roleId) > 0) {
                throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName()));
            }
        }
        sysRoleMenuMapper.deleteRoleMenu(roleIds);
        sysRoleDeptMapper.deleteRoleDept(roleIds);
        if (sysRoleMapper.deleteRoleByIds(roleIds) <= 0) {
            throw new ServiceException(MessageUtils.message("system.monitor.delete_error"));
        }
    }

    public int insertRoleDept(SysRole role) {
        int rows = 1;
        // 新增角色与部门（数据权限）管理
        List<SysRoleDept> list = new ArrayList<>();
        for (Long deptId : role.getDeptIds())
        {
            SysRoleDept rd = new SysRoleDept();
            rd.setRoleId(role.getRoleId());
            rd.setDeptId(deptId);
            list.add(rd);
        }
        if (!list.isEmpty()) {
            rows = sysRoleDeptMapper.batchRoleDept(list);
        }
        return rows;
    }

    public int insertRoleMenu(SysRole role) {
        int rows = 1;
        if(role.getMenuIds() == null) {
            throw new ServiceException(MessageUtils.message("system.role.menu_error"));
        }
        // 新增用户与角色管理
        List<SysRoleMenu> list = new ArrayList<>();
        for (Long menuId : role.getMenuIds()) {
            SysRoleMenu rm = new SysRoleMenu();
            rm.setRoleId(role.getRoleId());
            rm.setMenuId(menuId);
            list.add(rm);
        }
        if (!list.isEmpty()) {
            rows = sysRoleMenuMapper.batchRoleMenu(list);
        }
        return rows;
    }

    public void checkRoleAllowed(SysRole role) {
        if (StringUtils.isNotNull(role.getRoleId()) && role.isAdmin()) {
            throw new ServiceException(MessageUtils.message("system.role.super_role"));
        }
    }

    @Transactional
    public void updateRole(SysRole role) {
        role.setUpdateBy(SecurityUtils.getUsername());
        sysRoleMapper.updateRole(role);
        sysRoleMenuMapper.deleteRoleMenuByRoleId(role.getRoleId());
        if (insertRoleMenu(role) <= 0) {
            throw new ServiceException("更新失败，请稍后再试");
        }
    }

    public void updateRoleStatus(SysRole role) {
        checkRoleAllowed(role);
        checkRoleDataScope(role.getRoleId());
        role.setUpdateBy(SecurityUtils.getUsername());
        if (sysRoleMapper.updateRole(role) <= 0) {
            throw new ServiceException(MessageUtils.message("system.monitor.update_error"));
        }
    }

    public void deleteAuthUser(SysUserRole role) {
        if (sysUserRoleMapper.deleteUserRoleInfo(role) <= 0) {
            throw new ServiceException(MessageUtils.message("system.role.cancel_role_error"));
        }
    }

    public void deleteAuthUsers(Long roleId, Long[] userIds) {
        if (sysUserRoleMapper.deleteUserRoleInfos(roleId, userIds) <= 0) {
            throw new ServiceException(MessageUtils.message("system.role.cancel_role_error"));
        }
    }

    public void deleteRoleUsers(Long roleId) {
        sysUserRoleMapper.deleteRole(roleId);
    }

    @Transactional
    public void insertAuthUsers(Long roleId, Long[] userIds) {
        if (roleId == null) {
            throw new ServiceException(MessageUtils.message("system.role.create_error"));
        }
        deleteRoleUsers(roleId);
        checkRoleDataScope(roleId);
        if (userIds.length == 0) {
            return;
        }
        // 新增用户与角色管理
        List<SysUserRole> list = new ArrayList<>();
        for (Long userId : userIds) {
            SysUserRole ur = new SysUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        if (sysUserRoleMapper.batchUserRole(list) <= 0) {
            throw new ServiceException(MessageUtils.message("system.role.batch_role_error"));
        }
    }

}
